package com.example.ranl_safeapi.AOP;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@Aspect
public class ApiTrafficMonitorAspect {

    private AtomicInteger requestCount = new AtomicInteger(0);

    // 定义一个切点，监控所有GET请求
    @AfterReturning(pointcut = "execution(* com.example.ranl_safeapi.Controller.StudentController.*(..)) && @annotation(org.springframework.web.bind.annotation.GetMapping)", returning = "result")
    public void monitorTraffic(Object result) {
        requestCount.incrementAndGet();
    }

    // 定义一个方法来获取每秒请求量
    public int getRequestCountPerSecond() {
        return requestCount.getAndSet(0);
    }

    private Map<String, Long> startTimeMap = new HashMap<>();

    @Around("execution(* com.example.ranl_safeapi.Controller.StudentController.*(..))")
    public Object monitorTraffic(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录请求开始时间
        String methodName = joinPoint.getSignature().getName();
        long startTime = System.currentTimeMillis();
        startTimeMap.put(methodName, startTime);

        // 执行被拦截的方法
        Object result = joinPoint.proceed();

        // 记录请求结束时间，并计算耗时
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;

        // 输出请求耗时信息
        System.out.println("Request method: " + methodName + ", duration: " + duration + "ms");

        return result;
    }

    // 获取当前接口每条请求的平均响应时间
    public Map<String, Double> getAverageResponseTime() {
        Map<String, Double> averageResponseTimeMap = new HashMap<>();
        for (Map.Entry<String, Long> entry : startTimeMap.entrySet()) {
            String methodName = entry.getKey();
            Long startTime = entry.getValue();
            Long endTime = System.currentTimeMillis();
            Double averageResponseTime = (double) (endTime - startTime) / startTimeMap.size();
            averageResponseTimeMap.put(methodName, averageResponseTime);
        }
        return averageResponseTimeMap;
    }
}
